package controller.editor;

import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

import main.model.Attribute;
import main.model.Diagram;
import main.model.Entity;
import view.editor.EntityCreationView;
import controller.ButtonColumn;
import controller.ComponentController;
import controller.Controller;


public class EntityCreationController extends Controller implements ComponentController{

	private Diagram diagram;
	private Entity entity;
	private EntityCreationView view;
	private EditorController editorController;
	private AttributeCreationController controller; 
	private HashMap<String, Attribute> attributeMap;
	private List<String> attsNames;
	private String componentBeingEdited = null;
	private int attBeingEdited;
	
	public EntityCreationController(Diagram diagram, EditorController editorController) {
		this.diagram = diagram;
		this.entity = new Entity();
		this.attributeMap = new HashMap<String, Attribute>();
		this.editorController = editorController;
		this.setAttsNames(new ArrayList<String>());
	}
	
	@Override
	public void displayView() {
		this.view = new EntityCreationView();
		view.setController(this);
		view.show();	
	}

	public void handleButtonAddAttributes() {
		controller = new AttributeCreationController(this, this.editorController);
		controller.displayView();
	}

	public void handleButtonTerminar() {
		if (!"".equals(view.getEntityName())){
			if (view.getEntity() == null){
				if (!this.editorController.getProject().getComponentsNames().contains(view.getEntityName())){
					addAttributesToEntity();
					if (this.view.getTypeSelected().equals("Maestra")){
						this.entity.setIsMasterEntity(Boolean.TRUE);
					}else{
						this.entity.setIsMasterEntity(Boolean.FALSE);
					}
					this.entity.setName(view.getEntityName());
					this.entity.setDiagramParent(this.diagram.getName());
					this.diagram.addEntity(this.entity);
					this.editorController.notifyNewEntity(this.entity);
				} else {
					JDialog dialogo = new JDialog(); 
					JOptionPane.showMessageDialog(dialogo,"Ya existe un componente con ese nombre", "Notificacion",
			                    JOptionPane.INFORMATION_MESSAGE);
				}
			} else {
				this.editorController.getProject().removeComponentName(this.componentBeingEdited);
				this.editorController.getProject().addComponentName(this.entity.getName());
				this.entity.setName(view.getEntityName());
				if (this.view.getTypeSelected().equals("Maestra")){
					this.entity.setIsMasterEntity(Boolean.TRUE);
				}else{
					this.entity.setIsMasterEntity(Boolean.FALSE);
				}
				addAttributesToEntity();
				this.editorController.notifyEditedEntity(this.entity);
			}
		} else {
			JDialog dialogo = new JDialog(); 
			JOptionPane.showMessageDialog(dialogo,"No puede generar una entidad sin nombre", "Notificacion",
	                    JOptionPane.INFORMATION_MESSAGE);
		}
		view.hide();
	}
	
	@SuppressWarnings("rawtypes")
	private void addAttributesToEntity() {
		int i;
		int cant_row = view.getAttributesToEntity().getRowCount();
		this.entity.removeAllAttributes();
		for (i = 0; i<cant_row; i++){
			String atribut = ((Vector) view.getAttributesToEntity().getDataVector()
					.elementAt(i)).elementAt(0).toString();
			Object esId = ((Vector) view.getAttributesToEntity().getDataVector()
					.elementAt(i)).elementAt(2);
			if (esId != null && esId.toString().equals("Si")){
				this.entity.addIdAttribute(this.attributeMap.get(atribut));
			} else {
				this.entity.addAttribute(this.attributeMap.get(atribut));
			}
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes", "serial", "unused" })
	@Override
	public void addAttributeToComponent(Attribute att) {
		String name = att.getName();
		if (this.attsNames.contains(name)){
			JDialog dialogo = new JDialog(); 
			JOptionPane.showMessageDialog(dialogo,"Ya existe un atributo con ese nombre", "Notificacion",
	                    JOptionPane.INFORMATION_MESSAGE);
		} else {
			this.attributeMap.put(name, att);
			Vector rowData = new Vector(2);
			rowData.insertElementAt(name,0);
			rowData.insertElementAt("(" + att.getCardinality().getMin() + "," + att.getCardinality().getMax() + ")", 1);
			this.view.getAttributesToEntity().addRow(rowData);
			JComboBox comboBox = new JComboBox(new String[] {"Si", "No"});
			TableColumn colCardinalidad = view.getTablaAtributos().getColumnModel().getColumn(2);
			colCardinalidad.setCellEditor(new DefaultCellEditor(comboBox));
			int cant_row = view.getAttributesToEntity().getRowCount() - 1 ;
			((Vector) view.getAttributesToEntity().getDataVector()
					.elementAt(cant_row)).setElementAt("Editar", 3);
			((Vector) view.getAttributesToEntity().getDataVector()
					.elementAt(cant_row)).setElementAt("Borrar", 4);
			if (this.entity.getIdAttributes().contains(att)){
				((Vector) view.getAttributesToEntity().getDataVector()
						.elementAt(cant_row)).setElementAt("Si", 2);
			} else {
				((Vector) view.getAttributesToEntity().getDataVector()
						.elementAt(cant_row)).setElementAt("No", 2);
			}
			Action edit = new AbstractAction()
			{
			    public void actionPerformed(ActionEvent e)
			    {
			        editAttribute();
			    }
			};
			Action delete = new AbstractAction()
			{
			    public void actionPerformed(ActionEvent e)
			    {
			    	deleteAttribute();
			    }
			};

			ButtonColumn editColumn = new ButtonColumn(view.getTablaAtributos(), edit, 3);
			ButtonColumn deleteColumn = new ButtonColumn(view.getTablaAtributos(), delete, 4);
			this.attsNames.add(name);
		}
	}
	
	@SuppressWarnings("rawtypes")
	public void deleteAttribute(){
		DefaultTableModel model = (DefaultTableModel) this.view.getAttributesToEntity();
		int[] rows = this.view.getTablaAtributos().getSelectedRows();
		int index = rows[0];
		String atribut = ((Vector) view.getAttributesToEntity().getDataVector()
				.elementAt(index)).elementAt(0).toString();
		if (this.view.getEntity() != null){
			Attribute att = this.attributeMap.get(atribut);
			this.view.getEntity().removeAttribute(att);
			this.view.getEntity().removeIdAttribute(att);
		}
		this.attributeMap.remove(atribut);
		model.removeRow(index);
		
	}
	
	@SuppressWarnings("rawtypes")
	public void editAttribute(){
		int[] rows = this.view.getTablaAtributos().getSelectedRows();
		int index = rows[0];
		this.attBeingEdited = index;
		String atribut = ((Vector) this.view.getAttributesToEntity().getDataVector()
				.elementAt(index)).elementAt(0).toString();
		Attribute a = this.attributeMap.get(atribut);
		controller = new AttributeCreationController(this, this.editorController);
		controller.displayEditView(a);
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public void updateAttribute(Attribute attribute) {
		String atribut = ((Vector) this.view.getAttributesToEntity().getDataVector()
				.elementAt(this.attBeingEdited)).elementAt(0).toString();
		Attribute removedAttr = this.attributeMap.remove(atribut);
		this.editorController.bindPointsToNewComponent(removedAttr, attribute);
		this.attributeMap.put(attribute.getName(), attribute);
		((Vector) this.view.getAttributesToEntity().getDataVector()
				.elementAt(this.attBeingEdited)).setElementAt(attribute.getName(), 0);
		((Vector) this.view.getAttributesToEntity().getDataVector()
				.elementAt(this.attBeingEdited)).setElementAt(attribute.getCardinality().toString(), 1);
		this.view.getAttributesToEntity().fireTableDataChanged();
		
	}

	public void editEntity(Entity e) {
		this.entity = e;
		Iterator<Attribute> iterator = this.entity.getAttributes().iterator();
		while (iterator.hasNext()){
			Attribute next = iterator.next();
			this.attributeMap.put(next.getName(), next);
		}
		iterator = this.entity.getIdAttributes().iterator();
		while (iterator.hasNext()){
			Attribute next = iterator.next();
			this.attributeMap.put(next.getName(), next);
		}
		this.view = new EntityCreationView();
		this.view.setEntity(e);
		this.componentBeingEdited = e.getName();
		view.setController(this);
		view.show();
		view.fillEntityData();
	}

	public void setAttsNames(List<String> attsNames) {
		this.attsNames = attsNames;
	}

	public List<String> getAttsNames() {
		return attsNames;
	}
	
}
